import fl from '@king-fisher/falcon';
// 获得距离顶部的距离
function getDistanceFromTop(element) {
  const rect = element.getBoundingClientRect();
  const height = element.offsetHeight;
  return rect.top + height;
}

// 监听滚动停止
function detectScrollStop(callback, delay) {
  let scrollTimer = null;
  return function () {
    clearTimeout(scrollTimer);
    scrollTimer = setTimeout(callback, delay);
  };
}

/**
 * 格式化数字为指定格式的字符串
 * @param {number} num - 要格式化的数字
 * @param {string} formatStr - 格式字符串，例如 'M.2'、'M.2%' 或 '+M.2%'
 * @returns {string|number} 格式化后的字符串或原始数字（如果无法格式化）
 */
function formatNumber(num, formatStr) {
  // 验证输入的数字和格式字符串是否有效
  if (typeof num === 'number' && formatStr) {
    // 判断格式字符串是否包含正负号
    const hasPlusSign = formatStr.startsWith('+');
    if (hasPlusSign) {
      formatStr = formatStr.substring(1); // 去掉正负号部分进行后续处理
    }

    // 检查格式字符串是否以 'M.' 开头
    if (formatStr.startsWith('M.')) {
      // 提取小数位数
      const num2 = 2;
      const decimalPlaces = parseInt(formatStr.substring(num2));

      // 如果小数位数有效，则格式化数字
      if (!isNaN(decimalPlaces) && decimalPlaces >= 0) {
        let formattedNum = num.toFixed(decimalPlaces);

        // 如果格式字符串以 '%' 结尾，则添加百分号
        if (formatStr.endsWith('%')) {
          formattedNum += '%';
        }

        // 根据需要在数字前添加正负号
        if (hasPlusSign) {
          formattedNum = (num >= 0 ? '+' : '') + formattedNum;
        }

        return formattedNum + '';
      }
    }
  }

  // 如果无法格式化，则返回原始的 num
  return num + '';
}

// 下划线变驼峰
function convertKeysToCamelCase(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(item => convertKeysToCamelCase(item));
  }

  const camelCaseObj = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      let value = obj[key];
      // 如果属性值是对象或数组，则递归调用 convertKeysToCamelCase
      if (typeof value === 'object' && !Array.isArray(value)) {
        value = convertKeysToCamelCase(value);
      } else if (Array.isArray(value)) {
        value = value.map(item => convertKeysToCamelCase(item));
      } else {
        // sonar
      }
      const camelCaseKey = key.replace(/_(\w)/g, (match, p1) => p1.toUpperCase());
      camelCaseObj[camelCaseKey] = value;
    }
  }
  return camelCaseObj;
}

/**
 * 跳转客户端股票分时页
 * @param {string | number} stockCode 股票代码
 * @param {string | number} marketId 市场id
 */
function jumpToFenShi(stockCode, marketId) {
  location.href = `client://client.html?action=ymtz^webid=2205^stockcode=${stockCode}^marketid=${marketId}`;
}

class DatePlus extends Date {
  constructor(args) {
    args ? super(args) : super();
  }
  format(fmt = 'yyyy-MM-dd hh:mm:ss') {
    const quarterlyMonths = 3;
    const o = {
      //月份
      'M+': this.getMonth() + 1,
      'd+': this.getDate(),
      'h+': this.getHours(),
      'm+': this.getMinutes(),
      's+': this.getSeconds(),
      'q+': Math.floor((this.getMonth() + quarterlyMonths) / quarterlyMonths),
      S: this.getMilliseconds(),
    };
    if (/(y+)/.test(fmt)) {
      fmt = fmt.replace(RegExp.$1, `${this.getFullYear()}`.substr(quarterlyMonths + 1 - RegExp.$1.length));
    }
    for (const k in o) {
      if (new RegExp(`(${k})`).test(fmt)) {
        fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length));
      }
    }
    return fmt;
  }
}

/**
 * Description
 * @param {string} dateTimeStr - "2024-03-14 15:25:00"
 * @param {string} startTimeStr - "9:30"
 * @param {string} endTimeStr - "10:30"
 * @returns {boolean}
 */
function isTimeInRange(dateTimeStr, startTimeStr, endTimeStr) {
  // 将日期时间字符串转换为 Date 对象
  const dateTime = new Date(dateTimeStr);
  // 获取时间段的开始时间和结束时间的小时和分钟
  const [startHour, startMinute] = startTimeStr.split(':').map(Number);
  const [endHour, endMinute] = endTimeStr.split(':').map(Number);

  // 构造时间段的开始和结束的 Date 对象
  const startDate = new Date(dateTime);
  startDate.setHours(startHour);
  startDate.setMinutes(startMinute);

  const endDate = new Date(dateTime);
  endDate.setHours(endHour);
  endDate.setMinutes(endMinute);

  // 检查 dateTime 是否在 startDate 和 endDate 之间
  return dateTime >= startDate && dateTime <= endDate;
}

const NUM2 = 2;
function convertNumber(number, unit, fixedNum = NUM2) {
  number = parseFloat(number);
  if (typeof number !== 'number') {
    return number;
  } else if (isNaN(number)) {
    return '--';
  } else {
    // sonar
  }

  // 使用英文单词作为单位的键
  const units = {
    tenThousand: 1e4,
    hundredMillion: 1e8,
  };

  // 添加映射关系，将英文单词单位映射到汉字单位
  const unitNames = {
    tenThousand: '万',
    hundredMillion: '亿',
  };

  if (!units.hasOwnProperty(unit)) {
    return number;
  }

  const unitValue = units[unit];
  const unitName = unitNames[unit];

  if (number % unitValue === 0) {
    return `${number / unitValue} ${unitName}`;
  } else {
    return `${(number / unitValue).toFixed(fixedNum)} ${unitName}`;
  }
}

// 节流
function throttle(cb, time) {
  let timer;
  return function (...args) {
    if (timer) {
      return;
    }
    timer = setTimeout(function () {
      timer = null;
      cb(...args);
    }, time);
  };
}

// 错误上报
const errorReport = ({ name, message, stack, category = 'ajax' }) => {
  window.ClientMonitor.reportFrameErrors(
    {
      // 类型
      category,
      // 级别
      grade: 'Error',
    },
    {
      name,
      message,
      stack,
    }
  );
};

/**
 * 对数组中的对象按照指定属性进行排序
 * @param {Array} arr - 要排序的数组，每个元素是一个对象
 * @param {string} key - 对象的属性名，按照该属性进行排序
 * @param {number} [order=1] - 排序顺序，1 表示正序，-1 表示倒序，默认为正序
 * @returns {Array} 排序后的数组
 */
function customSort(arr, key, order = 1) {
  // 排序函数
  const sortByKey = (a, b) => {
    const aValue = a[key];
    const bValue = b[key];
    if (typeof aValue === 'string' && typeof bValue === 'string') {
      return order === 1 ? aValue.localeCompare(bValue, 'zh') : bValue.localeCompare(aValue, 'zh');
    } else {
      return order * (aValue - bValue);
    }
  };
  // 根据指定的 key 进行排序
  arr.sort(sortByKey);
  return arr;
}

// 获取标题栏目状态栏px高度，默认44px
function getHeaderHeightPx() {
  const headerHeight = 44;
  let statusBarHeight = null;
  try {
    statusBarHeight = fl.getWindowInfo().statusBarHeight;
  } catch (error) {
    statusBarHeight = headerHeight;
  }
  return statusBarHeight + headerHeight;
}

/**
 * 获取个股板块标签
 * @param {string} kjb - 空间板(0/1)
 * @param {string} lt - 龙头板(0/1)
 * @returns {string} 标签
 */
function getBoardTag(kjb, lt) {
  if (kjb) {
    return '空间';
  } else if (!kjb && lt) {
    return '龙头';
  } else {
    return '';
  }
}

/**
 * 获取带行情数据的table
 * @param {string[]} {stockcodes
 * @param {string[]} marketids
 * @param {string[]} tableData}
 * @returns {any}
 */
function getMarketInfoTable({ stockcodes, marketids, tableData }) {
  // 将table深拷贝一层，防止修改原table
  const nowTableData = JSON.parse(JSON.stringify(tableData));
  return new Promise(resolve => {
    if (window.getAppVersion() && stockcodes.length) {
      // 10: 价格，34818: 涨幅, 48:涨速
      window.__getMarketInfo(['10', '34818', '48'], stockcodes, marketids, data => {
        const { 10: price, 34818: upRise, 48: upRate } = data;
        for (let index = 0; index < stockcodes.length; index++) {
          nowTableData[index].upRise = upRise[index] === '--' ? '--' : parseFloat(upRise[index]);
          nowTableData[index].price = price[index] === '--' ? '--' : parseFloat(price[index]);
          nowTableData[index].acceleration = upRate[index] === '--' ? '--' : parseFloat(upRate[index]);
        }
        resolve(nowTableData);
      });
    } else {
      resolve(nowTableData);
    }
  });
}

// date形如'yyyyMMdd' - 将日期字符串变成可格式化的日期
function formatDate(date, joinTips = '/') {
  const YEARNUM = 4;
  const MONTHNUM = 6;
  const DAYNUM = 8;
  return `${date.slice(0, YEARNUM)}${joinTips}${date.slice(YEARNUM, MONTHNUM)}${joinTips}${date.slice(
    MONTHNUM,
    DAYNUM
  )}`;
}

function highLight(originValue, searchValue, color) {
  return originValue.replaceAll(searchValue, `<span style="color: ${color}">${searchValue}</span>`);
}

function jump2804Url(url) {
  let urlTmp = url;
  if (!urlTmp || typeof urlTmp !== 'string') {
    return '';
  }
  if (window.getAppVersion() && urlTmp.indexOf('client.html') === -1) {
    !urlTmp.startsWith('http') && (urlTmp = window.location.protocol + urlTmp);
    location.href= `client://client.html?action=ymtz^webid=2804^mode=new^url=${urlTmp}`;
  }
}

function jumpFullScreen(url,statusDarkMode='1') {
  if (window.getPlatform() === 'iphone') {
    let fullUrl = `client.html?action=ymtz^webid=2305^mode=new^StayHighForStatusBar=0^showStatusBar=1^url=${url}`;
    if (statusDarkMode || +statusDarkMode === 0) {
      fullUrl = `${fullUrl}^statusDarkMode=${statusDarkMode}`;
    }
    location.href = fullUrl;
  } else {
    location.href = `client.html?action=ymtz^webid=2804^mode=new^fullscreen=1^notitlebar=1^url=${url}`;
  }
}

function clientReplace(callback) {
  window.callNativeHandler(
    'goback',
    { type: window.getPlatform() === 'iphone' ? 'webview' : 'webpage' },
    () => {
      callback();
    }
  );
}


export {
  getHeaderHeightPx,
  getDistanceFromTop,
  detectScrollStop,
  formatNumber,
  convertKeysToCamelCase,
  jumpToFenShi,
  DatePlus,
  isTimeInRange,
  convertNumber,
  throttle,
  errorReport,
  customSort,
  getBoardTag,
  getMarketInfoTable,
  formatDate,
  highLight,
  jump2804Url,
  jumpFullScreen,
  clientReplace,
};
